home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / Mac OS X Throbber / DialogWatcher / RSO.INIT.c < prev   
Encoding:
C/C++ Source or Header  |  2000-06-24  |  6.4 KB  |  235 lines

  1. #include <Events.h>
  2. #include <Resources.h>
  3. #include <Memory.h>
  4. #include <ToolUtils.h>
  5. #include <Gestalt.h>
  6. #include <Errors.h>
  7. #include <StringCompare.h>
  8. #include <Sound.h>
  9.  
  10. #include "RSO.h"
  11.  
  12.     // some sane defaults in case we can't find our prefs.
  13. JiverGlobals    gJiverGlobs = {
  14.     1, // on by default
  15.     "\pJive"
  16. };
  17.  
  18. pascal short (*gOldSystemEvent)(EventRecord *ep);
  19. pascal short JiverSystemEvent(EventRecord *ep);
  20.  
  21. pascal void (*gOldModalDialog)(ModalFilterUPP modalFilter, DialogItemIndex *itemHit);
  22. pascal void JiverModalDialog(ModalFilterUPP modalFilter, DialogItemIndex *itemHit);
  23.  
  24. enum {
  25.     uppSystemEventProcInfo = kPascalStackBased | RESULT_SIZE(kTwoByteCode) | STACK_ROUTINE_PARAMETER(1, kFourByteCode)
  26. };
  27. enum {
  28.     uppModalDialogProcInfo = kPascalStackBased | RESULT_SIZE(kNoByteCode) | STACK_ROUTINE_PARAMETER(1, kFourByteCode) | STACK_ROUTINE_PARAMETER(2, kFourByteCode)
  29. };
  30.  
  31. SelectorFunctionUPP        ourGestaltUPP;
  32.  
  33. static pascal OSErr JiverGestalt(OSType selector, long *_response);
  34.  
  35. #ifdef powerc
  36.     // for Metrowerks' linker, this defines the interface for main().
  37.     ProcInfoType __procinfo = kCStackBased | RESULT_SIZE(kNoByteCode);
  38. #endif
  39.  
  40. void main(void)
  41. {
  42.     long                oldA4;
  43.     THz                    oldZone;
  44.     JiverGlobals        **bgh;
  45.     UniversalProcPtr    newSystemEventAddress;
  46.     UniversalProcPtr    newModalDialogAddress;
  47.  
  48.         // Set up A4, so we can access our globals.
  49.     oldA4 = SetCurrentA4();
  50.  
  51.         // Set the current zone to the system zone.  In the 680x0 case, this
  52.         // is not necessary, but it's not a bad idea and it keeps us out of
  53.         // trouble when traps that we don't expect to have side effects
  54.         // unexpectedlty allocate memory from the current zone.  One example
  55.         // of this is the NewRoutineDescriptor routine.
  56.     oldZone = GetZone();
  57.     SetZone(SystemZone());
  58.  
  59.         // OK, we're relying on gestalt, so we have to be sure that it's
  60.         // implemented.  We do this by checking to see that Gestalt's trap
  61.         // address is different from the address of unimplemented traps.
  62.     if (GetOSTrapAddress(kGestaltTrapNumber) == UnimplementedTrapAddress) goto initFailed;
  63.  
  64.     ourGestaltUPP = NewSelectorFunctionProc(JiverGestalt);
  65.     if (ourGestaltUPP == 0) goto initFailed;
  66.  
  67.     newSystemEventAddress = NewRoutineDescriptor((ProcPtr) &JiverSystemEvent,uppSystemEventProcInfo,GetCurrentArchitecture());
  68.     if (newSystemEventAddress == 0) goto initFailed;
  69.  
  70.     newModalDialogAddress = NewRoutineDescriptor((ProcPtr) &JiverModalDialog,uppModalDialogProcInfo,GetCurrentArchitecture());
  71.     if (newModalDialogAddress == 0) goto initFailed;
  72.  
  73.         // now install our gestalt selector, which sets up a mechanism for our control panel
  74.         // to talk to us and at the same time makes sure we're not loading twice.
  75.     if (NewGestalt(kDTS_Signature, ourGestaltUPP) != noErr) goto initFailed;
  76.  
  77.         // At this point, we have tested for any failure conditions, and nothing has gone wrong.
  78.         // So now is the time to detach our code, patch our traps, and settle in.
  79.     DetachResource(GetResource('INIT', -4048));
  80.  
  81.         // Remember the old implementation of SystemEvent
  82.     gOldSystemEvent = (void *) GetToolTrapAddress(kSystemEventTrapNumber);
  83.     gOldModalDialog = (void *) GetToolTrapAddress(kModalDialogTrapNumber);
  84.  
  85.         // Patch ourselves in.
  86.     SetToolTrapAddress(newSystemEventAddress, kSystemEventTrapNumber);
  87.     SetToolTrapAddress(newModalDialogAddress, kModalDialogTrapNumber);
  88.  
  89.     bgh = (JiverGlobals **)Get1Resource('pref', -4048);
  90.     if (bgh != 0 && GetHandleSize((Handle)bgh) == sizeof(gJiverGlobs)) {
  91.         gJiverGlobs = **bgh;
  92.     }
  93.  
  94. initFailed:
  95.         // Restore the old zone again
  96.     SetZone(oldZone);
  97.  
  98.         // And restore the value of A4 on the way out.
  99.     SetA4(oldA4);
  100. }
  101.  
  102. static pascal OSErr JiverGestalt(OSType selector, long *response) {
  103.     long    oldA4;
  104.     OSErr    err = noErr;
  105.  
  106.         // Set up A4, so we can access our globals.
  107.     oldA4 = SetCurrentA4();
  108.  
  109.     switch (selector) {
  110.         case kGestaltGetInitGlobals:
  111.             *response = (long)&gJiverGlobs;
  112.             break;
  113.         case kDTS_Signature:
  114.             *response = (long)ourGestaltUPP;
  115.             break;
  116.         case gestaltVersion:
  117.             *response = 0x0100;    // version 1.0 Gestalt interface for Jiver.
  118.             break;
  119.         default:
  120.             err = gestaltUnknownErr;
  121.             break;
  122.     }
  123.  
  124.         // Restore the value of A4 on the way out.
  125.     SetA4(oldA4);
  126.     return err;
  127. }
  128.  
  129. #if 0 // This is used for ReturnStillOpens
  130. pascal short JiverSystemEvent(EventRecord *ep)
  131. {
  132.         // Set up A4, so we can access our globals.
  133.     long        oldA4;
  134.     short        result;
  135.  
  136.     oldA4 = SetCurrentA4();
  137.  
  138.         // Check for keyDown events, and change return to command-O
  139.     if (gJiverGlobs.JiverOn) {
  140.         if (ep->what == keyDown && ep->modifiers == btnState && (ep->message & 0xFF) == '\r') {
  141.             if (*(long *)0x910 == *(long *)0x2E0) {
  142.                 ep->message = 'o' + (0xFFFFFF00 & ep->message);
  143.                 ep->modifiers |= cmdKey;
  144.             }
  145.         }
  146.     }
  147.  
  148.         // Call the old SystemEvent:
  149. #ifndef powerc
  150.     result = gOldSystemEvent(str);
  151. #else
  152.     result = CallUniversalProc((UniversalProcPtr)gOldSystemEvent, uppSystemEventProcInfo, ep);
  153. #endif
  154.         // And restore the value of A4 on the way out.
  155.     SetA4(oldA4);
  156.     return result;
  157. }
  158. #else
  159. WindowPtr gLastMD;
  160. pascal void JiverModalDialog(ModalFilterUPP modalFilter, DialogItemIndex *itemHit) {
  161.         // Set up A4, so we can access our globals.
  162.     long        oldA4;
  163.     short        result;
  164.  
  165.     oldA4 = SetCurrentA4();
  166.  
  167.     gLastMD = FrontWindow();
  168.  
  169.         // Call the old ModalDialog:
  170. #ifndef powerc
  171.     result = gOldModalDialog(str);
  172. #else
  173.     result = CallUniversalProc((UniversalProcPtr)gOldModalDialog, uppModalDialogProcInfo, modalFilter, itemHit);
  174. #endif
  175.  
  176.         // And restore the value of A4 on the way out.
  177.     SetA4(oldA4);
  178. }
  179.  
  180. static void LookForDefaultButton(void) {
  181.     WindowPtr        wp = FrontWindow();
  182.     WindowRecord *    wrp = (WindowRecord *)wp;
  183.     DialogItemType    itemType;
  184.     Handle             item;
  185.     Rect            r;
  186.  
  187.     r.top = 0;
  188.     r.bottom = 0;
  189.     r.left = 0;
  190.     r.right = 0;
  191.  
  192.     if (wp == gLastMD && wrp->controlList) {
  193.         DialogRecord *drp = (DialogRecord *)wrp;
  194.  
  195.         GetDialogItem(wp, drp->aDefItem, &itemType, &item, &r);
  196.         if (itemType != btnCtrl && itemType != resCtrl && itemType != ctrlItem) {
  197.             r.top = 0;
  198.             r.bottom = 0;
  199.             r.left = 0;
  200.             r.right = 0;
  201.         } else {
  202.             GrafPtr    gp;
  203.             GetPort(&gp);
  204.             SetPort(wp);
  205.             LocalToGlobal(0 + (Point *)&r);
  206.             LocalToGlobal(1 + (Point *)&r);
  207.             SetPort(gp);
  208.         }
  209.     }
  210.  
  211.     *(Rect *)0x40 = r;
  212. }
  213.  
  214. pascal short JiverSystemEvent(EventRecord *ep)
  215. {
  216.         // Set up A4, so we can access our globals.
  217.     long        oldA4;
  218.     short        result;
  219.  
  220.     oldA4 = SetCurrentA4();
  221.  
  222.         // Call the old SystemEvent:
  223. #ifndef powerc
  224.     result = gOldSystemEvent(str);
  225. #else
  226.     result = CallUniversalProc((UniversalProcPtr)gOldSystemEvent, uppSystemEventProcInfo, ep);
  227. #endif
  228.  
  229.     LookForDefaultButton();
  230.  
  231.         // And restore the value of A4 on the way out.
  232.     SetA4(oldA4);
  233.     return result;
  234. }
  235. #endif